﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VisionApp.Entity;
using VisionApp.Interface;
using System.IO;
using System.Drawing;
using OpenCvSharp;
using System.Windows.Media.Imaging;
using System.Diagnostics;
using System.Windows.Forms;

namespace VisionAppManager.Model
{
    public class VisionModel:ModelBase
    {
        private VSResultContainer _rstCtnr;
        private List<VSResultContainer> _rstCtnrList = new List<VSResultContainer>();
        private Logger _log;
        private CfgIO _cfg;
        private CarModel _carModel;
        private string _barCode;
        private string _basePath;
        private string _imagePath;
        private VideoWriter _vw1,_vw2;
        public bool ResultOK { get; set; }
        public string FindBarCode { get; set; }
        private VSCfgData _cfgData;
        public VSCfgData CfgData
        {
            get
            {
                return _cfgData;
            }
            set
            {
                Set<VSCfgData>(ref _cfgData, value);
            }
        }
        public VisionModel(ILogger log, ICfgIO cfg)
        {
            _log = (Logger)log;
            _cfg = (CfgIO)cfg;
            _cfgData = new VSCfgData();
            _cfg.Load("VSCfgData", ref _cfgData);
            if (_cfgData == null)
            {
                _cfgData = new VSCfgData();
                _cfg.Save("VSCfgData", _cfgData);
            }
            _rstCtnr = new VSResultContainer();
        }
        public int Init()
        {
            try
            {
                SetCarModel(CarModel.Model1);
                _log.Imformation(string.Format("Load all calibration data"));
                clearRstCtnrList();
                _basePath = System.Environment.CurrentDirectory + "\\Images\\" + _carModel.ToString() + "\\";
                Connected = true;
                return 0;
            }
            catch (Exception e)
            {
                _log.Error(string.Format("Fail to load all calibration data "), e);
                return -1;
            }
        }
        public void SaveCfg()
        {
            _cfg.Save<VSCfgData>("VSCfgData", CfgData);
        }
        public void SetBarCode(string id)
        {
            _barCode = id;
            _log.Imformation("产品条码信息： "+ id);
        }
        public void SetCarModel(CarModel id)
        {
            _log.Imformation("车型信息： " + id);
            _carModel = id;
        }
        public void InitRawImage()
        {
            try
            {
                if (_barCode!=null && _barCode != "0000")
                {
                    _imagePath = _basePath + "Image\\" + _barCode + "\\";
                    if (!Directory.Exists(_imagePath))
                    {
                        Directory.CreateDirectory(_imagePath);
                    }
                }
                else
                {
                    _imagePath = _basePath + "Image\\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + "\\";
                    if (!Directory.Exists(_imagePath))
                    {
                        Directory.CreateDirectory(_imagePath);
                    }
                }
            }
            catch (Exception e)
            {
                _log.Error("SaveRawImage" + e.ToString());
            }
        }
        public void SaveRawImage(HImageContainer img)
        {
            try
            {
                Mat image = new Mat(img.TextHeight, img.TextWidth, MatType.CV_8UC3, img.ImGray);
                //_rstCtnr = new VSResultContainer();
                //_rstCtnr.Image = matToBitmapImage(image);
                //_rstCtnr.ID = img.ID;
                //_rstCtnrList.Add(_rstCtnr);
                //Messenger.Default.Send<VSResultContainer>(_rstCtnr);
                Cv2.ImWrite(_imagePath + DateTime.Now.ToString("mmssfff")+".png", image);
            }
            catch(Exception e)
            {
                _log.Error("SaveRawImage" + e.ToString());
            }
        }
        public void SaveRecordImage(HImageContainer img, int camID)
        {
            try
            {
                if (!Directory.Exists(_basePath))
                {
                    Directory.CreateDirectory(_basePath);
                }
                Mat image = new Mat(img.TextHeight, img.TextWidth, MatType.CV_8UC3, img.ImGray);
                if (img.ID == ImagePosID.LEFTCAM)
                {
                    Record(image, 1);
                }
                else
                {
                    Record(image, 2);
                }
            }
            catch (Exception e)
            {
                _log.Error("saveModelImage" + e.ToString());
                return;
            }
        }
        public void InitRecord()
        {
            try
            {
                string path = null;
                if (_barCode != null && _barCode != "0000")
                {
                    path = _basePath + "Video\\" + _barCode + "\\";
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                    _vw1 = new VideoWriter(path + "\\Record1.avi", FourCC.MJPG, _cfgData.FPS, new OpenCvSharp.Size(CfgData.Width, CfgData.Height), true);
                    _vw2 = new VideoWriter(path + "\\Record2.avi", FourCC.MJPG, _cfgData.FPS, new OpenCvSharp.Size(CfgData.Width, CfgData.Height), true);
                }
                else
                {
                    path = _basePath + "Video\\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + "\\";
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                    _vw1 = new VideoWriter(path + "\\Record1.avi", FourCC.MJPG, _cfgData.FPS, new OpenCvSharp.Size(CfgData.Width, CfgData.Height), true);
                    _vw2 = new VideoWriter(path + "\\Record2.avi", FourCC.MJPG, _cfgData.FPS, new OpenCvSharp.Size(CfgData.Width, CfgData.Height), true);
                }
            }
            catch(Exception e)
            {
                _log.Error("InitRecord" + e.ToString());
            }
        }
        public string GetRecordPath()
        {
            try
            {
                string path = null;
                if (_barCode != null && _barCode.Length > 0 && !_barCode.Contains("0000"))
                {
                    path = _basePath + "Video\\" + _barCode + "\\";
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                }
                else
                {
                    path = _basePath + "Video\\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + "\\";
                    if (!Directory.Exists(path))
                    {
                        Directory.CreateDirectory(path);
                    }
                }
                return path;
            }
            catch (Exception e)
            {
                _log.Error("InitRecord" + e.ToString());
                return null;
            }
        }
        public string GetImagePath()
        {
            try
            {
                if (_barCode != null && !_barCode.Contains("0000"))
                {
                    _imagePath = _basePath + "Image\\" + _barCode + "\\";
                    if (!Directory.Exists(_imagePath))
                    {
                        Directory.CreateDirectory(_imagePath);
                    }
                }
                else
                {
                    _imagePath = _basePath + "Image\\" + System.DateTime.Now.ToString("yyyyMMddhhmmss") + "\\";
                    _log.Imformation(_imagePath);
                    if (!Directory.Exists(_imagePath))
                    {
                        Directory.CreateDirectory(_imagePath);
                    }
                }
               
                return _imagePath;
            }
            catch (Exception e)
            {
                _log.Error("InitRecord" + e.ToString()+ _imagePath);
                return null;
            }
        }
        public void Record(Mat image, int id)
        {
            try
            {
                if (id == 1)
                    _vw1.Write(image);
                else
                    _vw2.Write(image);
            }
            catch (Exception e)
            {
                _log.Error("Record" + e.ToString());
            }
        }
        public void ExitRecord()
        {
            try
            {
                if (_vw1 != null)
                    _vw1.Release();
                if (_vw2 != null)
                    _vw2.Release();
            }
            catch (Exception e)
            {
                _log.Error("ExitRecord" + e.ToString());
            }
        }
        public int SearchVideo()
        {
            try
            {
                string basepath = System.Environment.CurrentDirectory + "\\Images\\" + _carModel.ToString() + "\\Video\\";
                string[] filename = Directory.GetDirectories(basepath);
                if (filename == null)
                {
                    _log.Imformation("找不到视频，请检查输入条码是否正确！");
                    return -1;
                }
                if (filename.Length==0 || FindBarCode==null)
                {
                    _log.Imformation("找不到视频，请检查输入条码是否正确！");
                    return -1;
                }
                foreach (string file in filename)
                {
                    if (file.Contains(FindBarCode))
                    {
                        _log.Imformation("找到视频，打开文件夹");
                        System.Diagnostics.Process.Start("explorer.exe", file);
                        //Process.Start(basepath + FindBarCode + "Record.avi");
                        return 0;
                    }
                }
                _log.Imformation("找不到视频，请检查输入条码是否正确！");
                return -1;
            }
            catch(Exception e)
            {
                _log.Error("找不到视频，请检查输入条码是否正确!");
                return -1;
            }         
        }
        public void UpdateImageView(HImageContainer img)
        {
            Mat image = new Mat(img.TextHeight, img.TextWidth, MatType.CV_8UC3, img.ImGray);
            _rstCtnr = new VSResultContainer();
            _rstCtnr.Image = matToBitmapImage(image);
            _rstCtnr.ID = img.ID;
            Messenger.Default.Send<VSResultContainer>(_rstCtnr);
        }
        private void clearRstCtnrList()
        {
            _rstCtnrList.Clear();
        }
        public Bitmap matToBitmap(Mat image)
        {
            return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(image);
        }
        private BitmapImage matToBitmapImage(Mat image)
        {
            Bitmap bitmap = matToBitmap(image);
            using (MemoryStream stream = new MemoryStream())
            {
                bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Png); // 坑点：格式选Bmp时，不带透明度
                stream.Position = 0;
                BitmapImage result = new BitmapImage();
                result.BeginInit();
                // According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
                // Force the bitmap to load right now so we can dispose the stream.
                result.CacheOption = BitmapCacheOption.OnLoad;
                result.StreamSource = stream;
                result.EndInit();
                result.Freeze();
                return result;
            }
        }
    }
}
